home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1994 November / Cd Ware (Nro. 2) - Epimundo.iso / DOS / PG / STRX.ZIP / REGX.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-17  |  6.0 KB  |  264 lines

  1. //
  2. // regx.cpp     : Define implementation for regular expression class
  3. // Author       : Roy S. Woll
  4. //
  5. // Copyright (c) 1993 by Roy S. Woll
  6. // You may distribute this source freely as long as you leave all files
  7. // in their original form, including the copyright notice as is.
  8. //
  9. //
  10. // Version 2.1      12/10/92
  11. //    Add copy constructor
  12. //
  13. // Version 2.00     11/31/92
  14. //    Define class for regular expressions.
  15. //
  16.  
  17. #include <iostream.h>
  18. #include <limits.h>
  19. #include <string.h>
  20. #include "regX.h"
  21. #include "regximp.h"
  22.  
  23. regXimp::regXimp(void):compiledPattern(256){
  24.    error = 1;
  25.    caseSensitive=1;
  26.    startMatch=endMatch=0;
  27. };
  28.  
  29.  
  30. regX::regX(void):imp(new regXimp()){};
  31.  
  32. regX::regX(const regX& r):imp(new regXimp())
  33. {
  34.    *imp = *r.imp;
  35. };
  36.  
  37. regX::regX(const char * regexp):imp(new regXimp())
  38. {
  39.    imp->makepat(regexp);
  40. };
  41.  
  42. regX::~regX(void){ delete imp;};
  43.  
  44. regX& regX::operator=(const char * regexp){
  45.    return *this = regX(regexp);
  46. };
  47.  
  48. regX& regX::operator=(const regX& r){
  49.    *imp = *r.imp;
  50.    return *this;
  51. };
  52.  
  53.  
  54. int regX::index(const char * s, int * matchLenPtr, int start,
  55.                     int p_caseSensitive) const
  56. {
  57.    if (error()) return -1;
  58.  
  59.    if ( imp->matchs(s+start, p_caseSensitive) ){
  60.       *matchLenPtr = imp->endMatch - imp->startMatch +1;
  61.       return imp->startMatch - s;
  62.    }
  63.    else {
  64.       *matchLenPtr = 0;
  65.       return -1;
  66.    };
  67. };
  68.  
  69. int regX::indexr(const char * s, int * matchLenPtr, int start,
  70.                     int p_caseSensitive) const
  71. {
  72.    if (error()) return -1;
  73.  
  74.     str tempstr;
  75.    if (start==str::END_OF_STRING) start = strlen(s)-1;
  76.     tempstr.assign(s,start+1);
  77.     
  78.    int pos=start+1;
  79.  
  80.    // Find first match
  81.     while (!imp->matchs(tempstr()+pos, p_caseSensitive)&& pos>=0) pos--;
  82.    
  83.    // Find non-match
  84.    if (pos>0)
  85.    {
  86.       pos--;
  87.         *matchLenPtr = imp->endMatch - imp->startMatch +1;
  88.  
  89.         while (pos>0) {
  90.           imp->matchs(tempstr()+pos, p_caseSensitive);
  91.           if (imp->startMatch!=tempstr(pos)) break;
  92.           *matchLenPtr = imp->endMatch - imp->startMatch +1;
  93.           pos--;
  94.       }
  95.       return pos+1;
  96.    }
  97.    else {
  98.       *matchLenPtr = 0;
  99.       return -1;
  100.    }
  101.  
  102. };
  103.  
  104. int regX::error(void) const{ return imp->error; };
  105.  
  106.  
  107. int str::index(const regX& reg, int start) const{
  108.    int matchlen;
  109.    return reg.index(*this, &matchlen, start, caseSensitive());
  110. };
  111.  
  112. int str::indexr(const regX& reg, int start) const{
  113.    int matchlen;
  114.    return reg.indexr(*this, &matchlen, start, caseSensitive());
  115. };
  116.  
  117.  
  118. int str::index(const regX& reg, int * matchLen, int start) const
  119. {
  120.    return reg.index(*this, matchLen, start, caseSensitive());
  121. };
  122.  
  123. int str::indexr(const regX& reg, int * matchLen, int start) const
  124. {
  125.    return reg.indexr(*this, matchLen, start, caseSensitive());
  126. };
  127.  
  128. int str::search(const regX& reg, int * startPtr) const{
  129.    return search(reg, 0, startPtr);
  130. };
  131.  
  132. int str::search(const regX& reg, int start) const{
  133.    return search(reg, 0, &start);
  134. };
  135.  
  136. int str::search(const regX& reg, str * matchPtr, int start) const{
  137.    return search(reg, matchPtr, &start);
  138. };
  139.  
  140. int str::search(const regX& reg, str * matchPtr, int * startPtr) const{
  141.  
  142.    int matchLen;
  143.    int start = reg.index(*this, &matchLen, *startPtr, caseSensitive());
  144.    if (start>=0) {
  145.       if (matchPtr) *matchPtr = operator()(start, matchLen);
  146.       if (startPtr) *startPtr = start;
  147.       return 1;
  148.    }
  149.    else {
  150.       if (matchPtr) *matchPtr = "";
  151.       if (startPtr) *startPtr = -1;
  152.       return 0;
  153.    };
  154.  
  155. };
  156.  
  157. int str::searchr(const regX& reg, int * startPtr) const{
  158.    return searchr(reg, 0, startPtr);
  159. };
  160.  
  161. int str::searchr(const regX& reg, int start) const{
  162.    return searchr(reg, 0, &start);
  163. };
  164.  
  165. int str::searchr(const regX& reg, str * matchPtr, int start) const{
  166.    return searchr(reg, matchPtr, &start);
  167. };
  168.  
  169. int str::searchr(const regX& reg, str * matchPtr, int * startPtr) const{
  170.  
  171.    int matchLen;
  172.    int start = reg.indexr(*this, &matchLen, *startPtr, caseSensitive());
  173.    if (start>=0) {
  174.       if (matchPtr) *matchPtr = operator()(start, matchLen);
  175.       if (startPtr) *startPtr = start;
  176.       return 1;
  177.    }
  178.    else {
  179.       if (matchPtr) *matchPtr = "";
  180.       if (startPtr) *startPtr = -1;
  181.       return 0;
  182.    };
  183.  
  184. };
  185.  
  186.  
  187. int str::replace(const regX& reg, const char* replaceStr,
  188.                  int start, int numReplacements)
  189. {
  190.   return replace(reg, replaceStr, &start, numReplacements);
  191. };
  192.  
  193. int str::replace(const regX& reg, const char* replaceStr,
  194.                  int* startPtr, int numReplacements)
  195. {
  196.    int& start = *startPtr;
  197.    if (numReplacements==0) return 0;
  198.  
  199.    int countReplacements=0, matchLen;
  200.    int replaceLen = strlen(replaceStr);
  201.  
  202.    do {
  203.       start = index(reg, &matchLen, start);
  204.       if (start<0) break;
  205.       countReplacements++;
  206.       operator()(start, matchLen) = replaceStr;
  207.       start+= replaceLen;           //skip past newly added data
  208.  
  209.       if (!--numReplacements) break;
  210.    } while (1);
  211.  
  212.    return countReplacements;
  213.  
  214. };
  215.  
  216. int str::replacer(const regX& reg, const char* replaceStr,
  217.                  int start, int numReplacements)
  218. {
  219.   return replacer(reg, replaceStr, &start, numReplacements);
  220. };
  221.  
  222. int str::replacer(const regX& reg, const char* replaceStr,
  223.                  int* startPtr, int numReplacements)
  224. {
  225.    int& start = *startPtr;
  226.    if (numReplacements==0) return 0;
  227.  
  228.    int countReplacements=0, matchLen;
  229.  
  230.    do {
  231.       start = indexr(reg, &matchLen, start);
  232.       if (start<0) break;
  233.       countReplacements++;
  234.       operator()(start, matchLen) = replaceStr;
  235.       start--;           //skip past newly added data
  236.  
  237.       if (!--numReplacements) break;
  238.    } while (1);
  239.  
  240.    return countReplacements;
  241.  
  242. };
  243.  
  244. int str::replaceAll(const regX& reg, const char* replaceStr, int start)
  245. {
  246.   return replace(reg, replaceStr, &start, INT_MAX);
  247. };
  248.  
  249.  
  250. int str::count(const regX& searchStr, int start)
  251. {
  252.     int countReplacements=0;
  253.     int matchLen;
  254.  
  255.     while (index(searchStr, &matchLen, start))
  256.    {
  257.         start+= matchLen;
  258.         countReplacements++;
  259.    }
  260.  
  261.     return countReplacements;
  262. };
  263.  
  264.